package cn.sangyy.org.service.impl;

import cn.sangyy.basic.common.code.CodeEnum;
import cn.sangyy.basic.constent.BaseConstants;
import cn.sangyy.basic.dto.SendEmailDto;
import cn.sangyy.basic.exception.CarAssert;
import cn.sangyy.basic.utils.*;
import cn.sangyy.org.domain.Employee;
import cn.sangyy.org.domain.Shop;
import cn.sangyy.org.domain.ShopAuditLog;
import cn.sangyy.org.domain.ShopEmployee;
import cn.sangyy.org.dto.ShopAdminDto;
import cn.sangyy.org.dto.ShopAuditDto;
import cn.sangyy.org.dto.ShopRegisterDto;
import cn.sangyy.org.mapper.EmployeeMapper;
import cn.sangyy.org.mapper.ShopAuditLogMapper;
import cn.sangyy.org.mapper.ShopEmployeeMapper;
import cn.sangyy.org.mapper.ShopMapper;
import cn.sangyy.org.service.IShopService;
import cn.sangyy.user.domain.LoginInfo;
import cn.sangyy.user.mapper.LoginInfoMapper;
import cn.sangyy.basic.raabbitmq.config.RegisterNoticeRabbitmqConfig;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sangyangyang
 * @since 2023-05-22
 */
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {

    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private ShopEmployeeMapper shopEmployeeMapper;
    @Autowired
    private ShopAuditLogMapper shopAuditLogMapper;
    @Autowired
    private SendEmail sendEmail;
    @Autowired
    private LoginInfoMapper loginInfoMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    @Transactional
    public void settlement(ShopRegisterDto dto) {
        //1、参数校验
          //1.1 空校验 用JSR303来校验的
          //1.2 两次密码校验
          //1.3判断店铺是否存在
        validate(dto);
        //2、店铺审核
        Shop shop = new Shop();
        BeanUtils.copyProperties(dto,shop);
        shop.setRegisterTime(new Date());
        String content = dto.getName()+","+dto.getAddress();
        //百度ai审核
        Map<String, Object> map = BaiduAuditUtils.censor(content, dto.getLogo());
        Boolean success = (Boolean) map.get("success");
        //2.1修改审核状态
        if(success){
            shop.setState(BaseConstants.Shop.STATE_WAIT_ACTIVE);
        }else {
            shop.setState(BaseConstants.Shop.STATE_REJECT_AUDIT);
        }
          //2.2保存店铺信息到数据库
        shopMapper.insert(shop);
        //2.3保存管理员信息到数据库
        ShopAdminDto admin = dto.getAdmin();
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("phone", admin.getPhone()));
        //保存管理员、店铺信息
        saveInfo(shop, admin, employees);
        //3、设置审核日志，发送激活邮件用rabbitmq
        String emailContent;
        SendEmailDto sendEmailDto;
        if(success){
            saveAuditLog(BaseConstants.ShopPass.STATE_IS_PASS,shop.getId(),0L,"系统审核通过！");
            //发送邮件到管理员邮箱激活
            emailContent = admin.getUsername()+"你好，你的"+shop.getName()+"店铺审核通过"
                    +"请前往<a href='http://localhost:8090/shop/active/"+shop.getId()+"'>去激活</a>";
            sendEmailDto = new SendEmailDto(admin.getEmail(), "店铺入驻激活",emailContent,shop.getLogo());
        }else {
            saveAuditLog(BaseConstants.ShopPass.STATE_NOT_PASS,shop.getId(),0L,map.get("message").toString());
            emailContent = map.get("message").toString();
            sendEmailDto = new SendEmailDto(admin.getEmail(), "店铺入驻审核不通过",emailContent,null);
        }
        //发送mq消息
        rabbitTemplate.convertAndSend(RegisterNoticeRabbitmqConfig.EXCHANGE_TOPICS_INFORM,
                "inform.email",sendEmailDto);
    }

    private void saveInfo(Shop shop, ShopAdminDto admin, List<Employee> employees) {
        Employee employee;
        if(employees != null && employees.size() > 0){
            //管理员存在
            employee = employees.get(0);
            //添加记录到中间表
            ShopEmployee shopEmployee = new ShopEmployee();
            shopEmployee.setEmployeeId(employee.getId());
            shopEmployee.setShopId(shop.getId());
            shopEmployee.setIsAdmin(BaseConstants.ShopAdmin.STATE_IS_ADMIN);
            shopEmployeeMapper.insert(shopEmployee);
        }else {
            //管理员不存在
            LoginInfo loginInfo = new LoginInfo();
            loginInfo.setType(0);
            loginInfo.setDisable(1);
            loginInfo.setUsername(admin.getUsername());
            loginInfo.setEmail(admin.getEmail());
            loginInfo.setPhone(admin.getPhone());
            String salt = UUID.randomUUID().toString();
            String password = MD5Utils.encrypByMd5("car"+salt+"register"+ admin.getPassword());
            loginInfo.setSalt(salt);
            loginInfo.setPassword(password);
            loginInfoMapper.insert(loginInfo);
            employee = new Employee();
            employee.setSalt(salt);
            employee.setLogininfoId(loginInfo.getId());
            employee.setUsername(admin.getUsername());
            employee.setPassword(password);
            employee.setPhone(admin.getPhone());
            employee.setEmail(admin.getEmail());
            employee.setCreateTime(new Date());
            employee.setState(1);
            employeeMapper.insert(employee);
            ShopEmployee shopEmployee = new ShopEmployee();
            shopEmployee.setEmployeeId(employee.getId());
            shopEmployee.setShopId(shop.getId());
            shopEmployee.setIsAdmin(BaseConstants.ShopAdmin.STATE_NOT_ADMIN);
            shopEmployeeMapper.insert(shopEmployee);
        }
    }

    private void validate(ShopRegisterDto shopRegisterDto){
        ShopAdminDto admin = shopRegisterDto.getAdmin();
        CarAssert.assertStrEquals(admin.getPassword(),admin.getConfirmPassword(), CodeEnum.TWO_PASSWORD_ERROR);
        EntityWrapper<Shop> wrapper = new EntityWrapper<>();
        wrapper.eq("name",shopRegisterDto.getName());
        List<Shop> shops = shopMapper.selectList(wrapper);
        CarAssert.assertListIsNull(shops,CodeEnum.TENANT_EXIST_ERROR);
    }

    private void saveAuditLog(Integer state,Long shopId,Long auditId,String note){
        ShopAuditLog shopAuditLog = new ShopAuditLog();
        shopAuditLog.setAuditId(auditId);//系统审核默认为0
        shopAuditLog.setAuditTime(new Date());
        shopAuditLog.setShopId(shopId);
        shopAuditLog.setState(state);
        shopAuditLog.setNote(note);
        shopAuditLogMapper.insert(shopAuditLog);
    }

    @Override
    public void updateShop(Shop entity) {
        entity.setUpdateTime(new Date());
        shopMapper.updateShop(entity);
    }

    @Override
    @Transactional
    public void audit(ShopAuditDto shopAuditDto, HttpServletRequest request) {
        Long id = shopAuditDto.getId();
        Integer state = shopAuditDto.getState();
        CarAssert.assertNotNull(state,"状态不能为空！");
        if(id != null){
            List<Shop> shops = shopMapper.selectList(new EntityWrapper<Shop>().eq("id", id));
            Shop shop = shops.get(0);
            shop.setState(state);
            shopMapper.updateById(shop);
            //审核日志
            addAuditLog(shopAuditDto, request, state, shop);
            //发送人工审核的邮件给店铺管理员
            Wrapper<ShopEmployee> wrapper = new EntityWrapper<ShopEmployee>().
                    eq("shop_id", id).and().eq("is_admin", 1);
            ShopEmployee shopEmployee = shopEmployeeMapper.selectList(wrapper).get(0);
            Long employeeId = shopEmployee.getEmployeeId();
            List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("id", employeeId));
            Employee employee = employees.get(0);
            String email = employee.getEmail();
            String context = employee.getRealName()+"你好！你的"+shop.getName()+"审核结果："+shopAuditDto.getNote();
            if(state != 4){
                //发送邮件到管理员邮箱激活
                new Thread(() -> {
                    String emailContent = context+" 店铺审核通过"
                            +"请前往<a href='http://localhost:8090/shop/active/"+shop.getId()+"'>去激活</a>";
                    sendEmail.sendMime("店铺入驻激活",emailContent,email,shop.getLogo());
                }).start();
            }else {
                //发送邮件到管理员邮箱,让其进行店铺信息修改
                new Thread(() -> {
                    sendEmail.sendSimple("店铺审核不通过",context,email);
                }).start();
            }
        }
    }

    private void addAuditLog(ShopAuditDto shopAuditDto, HttpServletRequest request, Integer state, Shop shop) {
        ShopAuditLog log = new ShopAuditLog();
        if(state == 4){
            log.setState(0);
        }else {
            log.setState(1);
        }
        log.setShopId(shop.getId());
        Employee loginInfo = LoginContext.getLoginInfo(request);
        Long loginInfoId = loginInfo.getId();
        log.setAuditId(loginInfoId);
        log.setAuditTime(new Date());
        log.setNote(shopAuditDto.getNote());
        shopAuditLogMapper.insert(log);
    }


}
